package com.grace.cms.general.taglib;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.grace.cms.common.enums.ArticleTypeEnums;
import com.grace.cms.common.enums.OrderEnums;
import com.grace.cms.general.cache.GeneralArticleVoCacheService;
import com.grace.cms.general.model.enums.ArticleCountSortEnum;
import com.grace.cms.query.model.vo.WebArticleVo;
import com.grace.redis.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 通过文章中访问量获取文章列表
 * 
 */
@Service("articleCountSortTag")
public class ArticleCountSortTag {

        @Autowired
        private GeneralArticleVoCacheService webArticleSortService;

        @Autowired
        private RedisCache redisCache;

        /**
         * 综合获取排序
         * 
         * @param num         页数
         * @param size        页面大小
         * @param articleType 文章类型
         * @param categoryId  分类ID
         * @param themeName   主题名字
         * @param sort        排序字段
         * @param order       排序方式
         * @return
         */
        public List<WebArticleVo> listArticlesVo(int num, int size, ArticleTypeEnums articleType, Long categoryId,
                        String themeName,
                        ArticleCountSortEnum sort, OrderEnums order) {
                return this.listArticleBy(num, size, articleType.ordinal(), categoryId, themeName,
                                sort.getOrder(order));
        }

        /**
         * 通过文章类型获取
         * 
         * @param num         页数
         * @param size        页面大小
         * @param articleType 文章类型
         * @param themeName   主题名字
         * @param sort        排序字段
         * @param order       排序方式
         * @return
         */
        public List<WebArticleVo> listArticlesVoByType(int num, int size, ArticleTypeEnums articleType,
                        String themeName,
                        ArticleCountSortEnum sort, OrderEnums order) {
                return this.listArticleBy(num, size, articleType.ordinal(), null, themeName, sort.getOrder(order));
        }

        /**
         * 通过文章统计获取
         * 
         * @param pageNum  第几页
         * @param pageSize 每页大小
         * @param sort     排序字段
         * @param order    排序方式
         * @return
         */
        public List<WebArticleVo> listWebArticleOrder(int pageNum, int pageSize, ArticleCountSortEnum sort,
                        OrderEnums order) {
                return this.listArticleBy(pageNum, pageSize, null, null, null,
                                sort.getOrder(order));
        }

        /**
         * 通过主题名
         * 
         * @param pageNum
         * @param pageSize
         * @param themeName
         * @param sort
         * @param order
         * @return
         */
        public List<WebArticleVo> listWebArticleOrder(int pageNum, int pageSize, String themeName,
                        ArticleCountSortEnum sort, OrderEnums order) {
                return this.listArticleBy(pageNum, pageSize, null, null, themeName,
                                sort.getOrder(order));
        }

        /**
         * 通过文章类型
         * 
         * @param pageNum
         * @param pageSize
         * @param articleType
         * @param themeName
         * @param sort
         * @param order
         * @return
         */
        public List<WebArticleVo> listWebArticleOrderByType(int pageNum, int pageSize, Integer articleType,
                        String themeName,
                        ArticleCountSortEnum sort, OrderEnums order) {
                return this.listArticleBy(pageNum, pageSize, articleType, null, themeName,
                                sort.getOrder(order));
        }

        /**
         * 通过分类ID
         * 
         * @param themeName
         * @param categoryId
         * @param pageNum
         * @param pageSize
         * @param sort
         * @param order
         * @return
         */
        public List<WebArticleVo> listWebArticleOrderByCategoryId(String themeName, long categoryId, int pageNum,
                        int pageSize, ArticleCountSortEnum sort, OrderEnums order) {
                return this.listArticleBy(pageNum, pageSize, null, categoryId, themeName,
                                sort.getOrder(order));
        }

        /**
         * 上下
         * 
         * @param articleId
         * @param themeName
         * @return
         */
        public List<WebArticleVo> selectPreAndNextArticle(long articleId, String themeName) {
                List<Long> ids = webArticleSortService.preAndNextArticleId(articleId, themeName);
                ArrayList<Object> articleIdObjects = new ArrayList<>(ids.stream()
                                .map(Object::toString)
                                .collect(Collectors.toList()));
                List<WebArticleVo> listArticle = redisCache.getMultiCacheMapValue(
                                GeneralArticleVoCacheService.baseKeyPrefix,
                                articleIdObjects);

                for (WebArticleVo webArticleVo : listArticle) {
                        if (webArticleVo == null) {
                                webArticleVo = webArticleSortService.selectArticleById(articleId, themeName);
                                if (webArticleVo != null)
                                        listArticle.add(webArticleVo);
                        }
                }
                return listArticle.stream()
                                .filter(Objects::nonNull)
                                .collect(Collectors.toList());

        }

        public List<Long> listArticleVoIds(int num, int size, Integer articleType, Long categoryId,
                        String themeName,
                        String order) {
                return webArticleSortService.listArticleVoIds(num, size, articleType, categoryId, themeName, order);

        }

        public List<WebArticleVo> listArticleBy(int num, int size, Integer articleType, Long categoryId,
                        String themeName,
                        String order) {
                List<Long> ids = this.listArticleVoIds(num, size, articleType, categoryId, themeName, order);
                ArrayList<Object> articleIdObjects = new ArrayList<>(ids.stream()
                                .map(Object::toString)
                                .collect(Collectors.toList()));
                List<WebArticleVo> listArticle = redisCache.getMultiCacheMapValue(
                                GeneralArticleVoCacheService.baseKeyPrefix,
                                articleIdObjects);

                if (listArticle.stream().anyMatch(article -> article == null)) {
                        return changWebArticleVos(listArticle, articleIdObjects, num, size, articleType, categoryId,
                                        themeName, order);
                } else {
                        return listArticle;
                }

        }

        private List<WebArticleVo> changWebArticleVos(List<WebArticleVo> listArticle, List<Object> articleIdObjects,
                        int num, int size, Integer articleType, Long categoryId,
                        String themeName,
                        String order) {
                // 创建一个新的列表用于保存非空的 WebArticleVo 项
                List<WebArticleVo> nonNullArticles = new ArrayList<>();
                // 迭代 listArticle
                for (int i = 0; i < listArticle.size(); i++) {
                        WebArticleVo article = listArticle.get(i);
                        if (article != null) {
                                // 如果当前项不为 null，则添加到新列表中
                                nonNullArticles.add(article);
                        } else {
                                Long notArticleId = Long.valueOf(articleIdObjects.get(i).toString());
                                WebArticleVo webArticleVo = webArticleSortService.selectArticleById(notArticleId,
                                                themeName);
                                if (webArticleVo != null) {
                                        nonNullArticles.add(webArticleVo);
                                } else {
                                        // 清除缓存
                                }
                        }
                }
                return nonNullArticles;
        }
}
